package git.soulbgm.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import git.soulbgm.common.base.BaseController;
import git.soulbgm.common.enums.Status;
import git.soulbgm.common.pojo.QueryDto;
import git.soulbgm.common.pojo.Response;
import git.soulbgm.pojo.NodeStatus;
import git.soulbgm.pojo.ServiceStarting;
import git.soulbgm.service.NodeStatusService;
import git.soulbgm.service.ServiceStartingService;
import git.soulbgm.service.StartupService;
import git.soulbgm.utils.EasyPoiUtil;
import git.soulbgm.utils.StringUtil;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

import static git.soulbgm.common.MonitorConstants.*;

/**
 * 节点状态控制器
 *
 * @author SoulBGM
 * @date 2022/03/11 10:28
 */
@RestController
@RequestMapping("system/nodeStatus")
public class NodeStatusController extends BaseController {

    private final NodeStatusService nodeStatusService;
    private final StartupService startupService;
    private final ServiceStartingService serviceStartingService;

    public NodeStatusController(NodeStatusService nodeStatusService, StartupService startupService, ServiceStartingService serviceStartingService) {
        this.nodeStatusService = nodeStatusService;
        this.startupService = startupService;
        this.serviceStartingService = serviceStartingService;
    }

    @PostMapping("list")
    public Response list(@RequestBody QueryDto<NodeStatus> dto, Page<NodeStatus> queryPage) {
        Page<NodeStatus> resultPage = nodeStatusService.page(queryPage, new QueryWrapper<>(dto.getData()));
        return success(resultPage);
    }

    @GetMapping("export")
    public void export(NodeStatus info, HttpServletResponse response) {
        List<NodeStatus> list = nodeStatusService.list(new QueryWrapper<>(info));
        try {
            EasyPoiUtil.exportExcel(response, "主机状态数据", list, NodeStatus.class);
        } catch (IOException e) {
            throw new RuntimeException("导出失败");
        }
    }

    @PostMapping("online")
    public Response online(NodeStatus info) {
        return onlineAndOffline(info.getId(), ONLINE);
    }

    @PostMapping("offline")
    public Response offline(NodeStatus info) {
        return onlineAndOffline(info.getId(), OFFLINE);
    }

    /**
     * 在线和离线
     *
     * @param id   id
     * @param code 代码
     * @return {@link Response}
     */
    private Response onlineAndOffline(Long id, int code) {
        NodeStatus status = nodeStatusService.getById(id);
        boolean flag = (Status.NOT_INITIATED.code.equals(status.getStatus()) && code == ONLINE) ||
                (Status.NORMAL.code.equals(status.getStatus()) && code == OFFLINE);
        if (flag) {
            try {
                if (code == ONLINE) {
                    ServiceStarting starting = new ServiceStarting(status.getNodeCode(),
                            MONITOR_AGENT,
                            RULE_TYPE_NODE,
                            status.getDeployIp());

                    // 查看 启动表中是否有记录
                    ServiceStarting serviceStarting = serviceStartingService.getOne(new QueryWrapper<>(starting));
                    // 如果没有则添加
                    if (serviceStarting == null) {
                        serviceStartingService.save(starting);
                    } else {
                        return error("正在启动");
                    }
                }

                String commandResult = startupService.startupAndShutdownNode(status.getNodeCode(), code, true);
                if (commandResult.contains(NOT_SCRIPT_FILE)) {
                    return error(StringUtil.format("{}监控代理的脚本路径有误", code == ONLINE ? "启动" : "停止"));
                } else if (NOT_SUPPORT_OPERATION.equals(commandResult)) {
                    return error(NOT_SUPPORT_OPERATION);
                }
                if (code == ONLINE) {
                    status.setStatus(Status.STARTING.code);
                } else {
                    status.setStatus(Status.STOPPING.code);
                }
                boolean result = nodeStatusService.updateById(status);
                String message = StringUtil.format("{}{}", code == ONLINE ? "启动" : "停止", result ? "成功" : "失败");
                if (result) {
                    return success(message);
                } else {
                    return error(message);
                }
            } catch (Exception e) {
                String message = e.getMessage();
                if (message.contains(CONNECTION_TIMED_OUT)) {
                    return error("连接超时,请检查服务器是否启动");
                } else if (message.contains(AUTH_FAIL)) {
                    return error("SSH密码错误");
                } else {
                    return error(message);
                }
            }
        } else {
            flag = (Status.NORMAL.code.equals(status.getStatus()) && code == ONLINE)
                    || (Status.NOT_INITIATED.code.equals(status.getStatus()) && code == OFFLINE);
            if (flag) {
                return error(StringUtil.format("已{}", code == ONLINE ? "启动" : "停止"));
            } else {
                return error(StringUtil.format("正在{}...", code == ONLINE ? "启动" : "停止"));
            }
        }
    }

}
